package vip.xiaonuo.biz.modular.order.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.auth.core.pojo.SaBaseLoginUser;
import vip.xiaonuo.biz.modular.order.entity.BizFzOrder;
import vip.xiaonuo.biz.modular.order.entity.BizFzOrderDetail;
import vip.xiaonuo.biz.modular.order.entity.BizOrder;
import vip.xiaonuo.biz.modular.order.entity.BizUserTicket;
import vip.xiaonuo.biz.modular.order.entity.CacheOrederTick;
import vip.xiaonuo.biz.modular.order.entity.UserTickInfo;
import vip.xiaonuo.biz.modular.order.mapper.BizFzOrderDetailMapper;
import vip.xiaonuo.biz.modular.order.mapper.BizFzOrderMapper;
import vip.xiaonuo.biz.modular.order.mapper.BizTicketOrderMapper;
import vip.xiaonuo.biz.modular.order.param.BizTicketOrderAddParam;
import vip.xiaonuo.biz.modular.order.param.BizTicketOrderEditParam;
import vip.xiaonuo.biz.modular.order.param.BizTicketOrderIdParam;
import vip.xiaonuo.biz.modular.order.param.BizTicketOrderPageParam;
import vip.xiaonuo.biz.modular.order.param.BizOrderUpdateReservationTimeParam;
import vip.xiaonuo.biz.modular.order.param.BizTicketReservationQueryParam;
import vip.xiaonuo.biz.modular.order.result.BizTicketReservationResult;
import vip.xiaonuo.biz.modular.order.service.BizTicketOrderService;
import vip.xiaonuo.biz.modular.order.service.BizUserTicketService;
import vip.xiaonuo.biz.modular.ticket.entity.Ticket;
import vip.xiaonuo.biz.modular.ticket.service.TicketService;
import vip.xiaonuo.biz.modular.user.entity.BizUser;
import vip.xiaonuo.biz.modular.user.service.BizUserService;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 门票订单表Service接口实现类
 *
 * @author gtc
 *
 **/
@Slf4j
@Service
@EnableScheduling
public class BizTicketOrderServiceImpl extends ServiceImpl<BizTicketOrderMapper, BizOrder> implements BizTicketOrderService {



    @Autowired
    private TicketService ticketService;

    @Autowired
    private BizUserTicketService bizUserTicketService;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private BizTicketOrderMapper bizTicketOrderMapper;

    @Autowired
    private BizFzOrderMapper bizFzOrderMapper;

    @Autowired
    private BizFzOrderDetailMapper bizFzOrderDetailMapper;

    @Autowired
    private BizUserService bizUserService;

    @Override
    public Page<BizOrder> page(BizTicketOrderPageParam bizTicketOrderPageParam) {
        QueryWrapper<BizOrder> queryWrapper = new QueryWrapper<>();
        if(ObjectUtil.isNotEmpty(bizTicketOrderPageParam.getUserId())) {
            queryWrapper.lambda().eq(BizOrder::getUserId, bizTicketOrderPageParam.getUserId());
        }
        if(ObjectUtil.isNotEmpty(bizTicketOrderPageParam.getStatus())) {
            queryWrapper.lambda().eq(BizOrder::getStatus, bizTicketOrderPageParam.getStatus());
        }
        if(ObjectUtil.isAllNotEmpty(bizTicketOrderPageParam.getSortField(), bizTicketOrderPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(bizTicketOrderPageParam.getSortOrder());
            queryWrapper.orderBy(true, bizTicketOrderPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(bizTicketOrderPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByAsc(BizOrder::getId);
        }
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }


    private BlockingQueue<BizTicketOrderAddParam> orderTasks = new ArrayBlockingQueue<>(1024*1024);//阻塞队列
    private static final ExecutorService SECKILL_ORDER_EXECUTOR = Executors.newSingleThreadExecutor();//创建线程池

    @PostConstruct
    private void init(){//初始化执行方法
        SECKILL_ORDER_EXECUTOR.submit(new TicketOrderHandle());
        log.info("订单处理线程已启动");
    }

    /**
     * 定时任务：每分钟检查并关闭超时未支付的订单
     * 关闭超过30分钟仍未支付的订单
     */
    @Scheduled(cron = "0 * * * * ?") // 每分钟执行一次
    public void closeTimeoutOrders() {
        log.info("开始执行超时订单关闭定时任务");

        try {
            // 计算30分钟前的时间
            Date thirtyMinutesAgo = DateUtil.offsetMinute(new Date(), -30);

            // 查询所有待支付且创建时间超过30分钟的订单
            LambdaQueryWrapper<BizOrder> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(BizOrder::getStatus, "待支付")
                    .lt(BizOrder::getCreateTime, thirtyMinutesAgo);

            List<BizOrder> timeoutOrders = this.list(queryWrapper);

            if (timeoutOrders.isEmpty()) {
                log.info("没有需要关闭的超时订单");
                return;
            }

            log.info("发现{}个超时未支付订单，准备关闭", timeoutOrders.size());

            for (BizOrder order : timeoutOrders) {
                try {
                    // 获取分布式锁，防止并发修改
                    RLock lock = redissonClient.getLock("lock:order:close:" + order.getId());
                    if (lock.tryLock()) {
                        try {
                            // 再次检查订单状态，避免在获取锁期间状态已变更
                            BizOrder currentOrder = this.getById(order.getId());
                            if (currentOrder != null && "待支付".equals(currentOrder.getStatus())) {
                                // 更新订单状态为已关闭
                                currentOrder.setStatus("已关闭");
                                this.updateById(currentOrder);

                                // 恢复库存
                                ticketService.addInventory(currentOrder.getTicketId(), currentOrder.getTicketCount());

                                // 更新缓存中的库存
                                String cacheKey = "spot:ticketid:" + currentOrder.getTicketId();
                                String cacheValue = stringRedisTemplate.opsForValue().get(cacheKey);
                                if (StrUtil.isNotBlank(cacheValue)) {
                                    CacheOrederTick cacheOrderTick = CacheOrederTick.parseObj(cacheValue);
                                    cacheOrderTick.setInventory(cacheOrderTick.getInventory() + currentOrder.getTicketCount());
                                    stringRedisTemplate.opsForValue().set(cacheKey, cacheOrderTick.paresJson());
                                }

                                log.info("成功关闭超时订单：{}", currentOrder.getId());
                            }
                        } finally {
                            lock.unlock();
                        }
                    }
                } catch (Exception e) {
                    log.error("关闭超时订单{}失败", order.getId(), e);
                }
            }

            log.info("超时订单关闭定时任务执行完成");
        } catch (Exception e) {
            log.error("执行超时订单关闭定时任务异常", e);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(BizTicketOrderAddParam bizTicketOrderAddParam) throws InterruptedException {

        // 从缓存中获取门票库存
        String cacheKey = "spot:ticketid:" + bizTicketOrderAddParam.getTicketId();
        String cacheValue = stringRedisTemplate.opsForValue().get(cacheKey);


    //判空
        CacheOrederTick cacheOrderTick = Optional.ofNullable(cacheValue)
                .map(CacheOrederTick::parseObj)
                .orElseGet(() -> {//查询数据库，放到缓存中
                    Ticket ticket = ticketService.lambdaQuery().select(Ticket::getInventoryCount, Ticket::getPrice, Ticket::getStartTime, Ticket::getEndTime)
                            .eq(Ticket::getId, bizTicketOrderAddParam.getTicketId())
                            .one();
//                    Ticket ticket = ticketService.getById(bizTicketOrderAddParam.getTicketId());
                    Optional.ofNullable(ticket).orElseThrow(() -> new CommonException("门票不存在"));
                    CacheOrederTick newCacheOrderTick = CacheOrederTick.builder()
                            .inventory(ticket.getInventoryCount())
                            .tickprice(ticket.getPrice())
                            .startTime(ticket.getStartTime())
                            .endTime(ticket.getEndTime())
                            .build();
                    stringRedisTemplate.opsForValue().set(cacheKey, newCacheOrderTick.paresJson());
                    return newCacheOrderTick;
                });

        // 校验库存
        if (cacheOrderTick.getInventory() < bizTicketOrderAddParam.getTicketCount()) {
            throw new CommonException("门票库存不足");
        }
        //if (bizTicketOrderAddParam.getUserTickInfos().size() != bizTicketOrderAddParam.getTicketCount()) {
        //    throw new CommonException("购买数量不正确");
        //}

//        // 校验价格
//        if (cacheOrderTick.getTickprice().multiply(BigDecimal.valueOf(bizTicketOrderAddParam.getTicketCount()))
//                .compareTo(bizTicketOrderAddParam.getPrice()) != 0) {
//            throw new CommonException("价格不正确");
//        }
        // 直接使用后端计算价格下单
        bizTicketOrderAddParam.setPrice(cacheOrderTick.getTickprice().multiply(BigDecimal.valueOf(bizTicketOrderAddParam.getTicketCount())));

        // 更新邀请人id
        //if (StrUtil.isBlank(bizTicketOrderAddParam.getInvitationUserId())) {
            BizUser bizUser = bizUserService.getById(bizTicketOrderAddParam.getUserId());
            if (bizUser != null && bizUser.getInvitationUserId() != null) {
                bizTicketOrderAddParam.setInvitationUserId(bizUser.getInvitationUserId());
            }
        //}


        orderTasks.put(bizTicketOrderAddParam);//放到队列中

    }


    @Transactional(rollbackFor = Exception.class)
    public void createOrder(BizTicketOrderAddParam bizTicketOrderAddParam) throws CommonException{

            String cacheKey = "spot:ticketid:" + bizTicketOrderAddParam.getTicketId();
            CacheOrederTick cacheOrederTick;
            cacheOrederTick = CacheOrederTick.parseObj(stringRedisTemplate.opsForValue().get(cacheKey));
            //从缓存中取到票的数据
            BigDecimal totalPrice = cacheOrederTick.getTickprice().multiply(BigDecimal.valueOf(bizTicketOrderAddParam.getTicketCount()));
            BizOrder bizOrder = BeanUtil.toBean(bizTicketOrderAddParam, BizOrder.class);
            bizOrder.setPrice(totalPrice);
            bizOrder.setId(bizTicketOrderAddParam.getId());
            this.save(bizOrder);

            // 将生成的订单ID回写到bizTicketOrderAddParam
            // bizTicketOrderAddParam.setId(bizOrder.getId());

            //校验价格，写入数据库
            // 获取购票人信息列表和预订数量
            List<UserTickInfo> userTickInfos = bizTicketOrderAddParam.getUserTickInfos();
            int ticketCount = bizTicketOrderAddParam.getTicketCount();

            // 当用户信息少于购票数量时，使用第一个用户的信息填充
            if (userTickInfos.size() < ticketCount && !userTickInfos.isEmpty()) {
                UserTickInfo firstUserInfo = userTickInfos.get(0);

                // 先处理现有的用户信息
                for (UserTickInfo userInfo : userTickInfos) {
                    bizUserTicketService.add(userInfo, bizOrder.getId(), bizTicketOrderAddParam.getTicketId());
                }

                // 使用第一个用户信息填充剩余的票
                for (int i = userTickInfos.size(); i < ticketCount; i++) {
                    bizUserTicketService.add(firstUserInfo, bizOrder.getId(), bizTicketOrderAddParam.getTicketId());
                }
            } else {
                // 用户信息足够或为空，直接遍历处理
                for (UserTickInfo userInfo : userTickInfos) {
                    bizUserTicketService.add(userInfo, bizOrder.getId(), bizTicketOrderAddParam.getTicketId());
                }
            }

            //保存购票人的信息
            ticketService.reduceInventory(bizTicketOrderAddParam.getTicketId(), bizTicketOrderAddParam.getTicketCount());
            cacheOrederTick.setInventory(cacheOrederTick.getInventory() - bizTicketOrderAddParam.getTicketCount());
            stringRedisTemplate.opsForValue().set(cacheKey, cacheOrederTick.paresJson());
            //更新库存

    }

    //从阻塞队列中一直取数据
    private class TicketOrderHandle implements Runnable  {
        @Override
        public void run() {
            log.info("订单队列处理线程已启动");
            while (true) {
                BizTicketOrderAddParam bizTicketOrderAddParam = null;
                try {
                    bizTicketOrderAddParam = orderTasks.take(); // 从队列中取出一个订单
                    log.info("从队列中获取到订单，准备处理，订单ID: {}",
                            bizTicketOrderAddParam.getId() != null ? bizTicketOrderAddParam.getId() : "未指定");
                    handleTicketOrder(bizTicketOrderAddParam);
                } catch (InterruptedException e) {
                    log.error("队列处理线程被中断", e);
                    Thread.currentThread().interrupt(); // 重新设置中断标志
                    break; // 线程中断时退出循环
                } catch (CommonException e) {
                    log.error("处理订单时发生业务异常: {}", e.getMessage());
                    // 不重新抛出异常，避免线程终止
                    if (bizTicketOrderAddParam != null) {
                        log.info("订单处理失败: {}", bizTicketOrderAddParam.getId());
                    }
                } catch (Exception e) {
                    log.error("处理订单时发生未知异常", e);
                    // 不重新抛出异常，避免线程终止
                }
            }
            log.warn("订单队列处理线程已退出，这可能导致订单无法处理");
        }
    }

    // 加锁，获取分布式锁
    public void handleTicketOrder(BizTicketOrderAddParam bizTicketOrderAddParam) throws CommonException {
        if (bizTicketOrderAddParam == null) {
            log.error("订单参数为空，无法处理");
            return;
        }

        // 获取分布式锁
        RLock lock = redissonClient.getLock("lock:ticket:" + bizTicketOrderAddParam.getTicketId());
        boolean hasLock = false;

        try {
            // 尝试获取锁
            hasLock = lock.tryLock();
            if (!hasLock) {
                log.error("获取锁失败，可能存在并发下单，订单ID: {}", bizTicketOrderAddParam.getId());
                throw new CommonException("系统繁忙，请稍后再试");
            }

            log.info("获取锁成功，开始创建订单，ID: {}", bizTicketOrderAddParam.getId());
            // 直接调用本地方法，不使用代理对象
            this.createOrderDirectly(bizTicketOrderAddParam);
            log.info("订单创建成功，从队列中移除，ID: {}", bizTicketOrderAddParam.getId());
            orderTasks.remove(bizTicketOrderAddParam);
        } catch (IllegalStateException e) {
            log.error("创建订单时发生状态异常: {}", e.getMessage());
            throw new CommonException("下单失败: " + e.getMessage());
        } catch (Exception e) {
            log.error("创建订单时发生未知异常", e);
            throw new CommonException("下单失败，请稍后再试");
        } finally {
            // 释放锁
            if (hasLock) {
                try {
                    lock.unlock();
                    log.debug("已释放锁");
                } catch (Exception e) {
                    log.error("释放锁时发生异常", e);
                }
            }
        }
    }

    /**
     * 直接创建订单，不通过事务代理
     * 注意：此方法没有事务保护，需要在调用方法中处理事务
     */
    private void createOrderDirectly(BizTicketOrderAddParam bizTicketOrderAddParam) throws CommonException {
        String cacheKey = "spot:ticketid:" + bizTicketOrderAddParam.getTicketId();
        CacheOrederTick cacheOrederTick;
        cacheOrederTick = CacheOrederTick.parseObj(stringRedisTemplate.opsForValue().get(cacheKey));
        //从缓存中取到票的数据
        BigDecimal totalPrice = cacheOrederTick.getTickprice().multiply(BigDecimal.valueOf(bizTicketOrderAddParam.getTicketCount()));
        BizOrder bizOrder = BeanUtil.toBean(bizTicketOrderAddParam, BizOrder.class);
        bizOrder.setPrice(totalPrice);
        bizOrder.setId(bizTicketOrderAddParam.getId());
        bizOrder.setBookTime(bizTicketOrderAddParam.getBookTime());

        try {
            // 保存订单
            this.save(bizOrder);

            // 保存购票人信息
            // 获取购票人信息列表和预订数量
            List<UserTickInfo> userTickInfos = bizTicketOrderAddParam.getUserTickInfos();
            int ticketCount = bizTicketOrderAddParam.getTicketCount();

            // 当用户信息少于购票数量时，使用第一个用户的信息填充
            if (userTickInfos.size() < ticketCount && !userTickInfos.isEmpty()) {
                UserTickInfo firstUserInfo = userTickInfos.get(0);

                // 先处理现有的用户信息
                for (UserTickInfo userInfo : userTickInfos) {
                    bizUserTicketService.add(userInfo, bizOrder.getId(), bizTicketOrderAddParam.getTicketId());
                }

                // 使用第一个用户信息填充剩余的票
                for (int i = userTickInfos.size(); i < ticketCount; i++) {
                    bizUserTicketService.add(firstUserInfo, bizOrder.getId(), bizTicketOrderAddParam.getTicketId());
                }
            } else {
                // 用户信息足够或为空，直接遍历处理
                for (UserTickInfo userInfo : userTickInfos) {
                    bizUserTicketService.add(userInfo, bizOrder.getId(), bizTicketOrderAddParam.getTicketId());
                }
            }

            // 减少库存
            ticketService.reduceInventory(bizTicketOrderAddParam.getTicketId(), bizTicketOrderAddParam.getTicketCount());

            // 更新缓存
            cacheOrederTick.setInventory(cacheOrederTick.getInventory() - bizTicketOrderAddParam.getTicketCount());
            stringRedisTemplate.opsForValue().set(cacheKey, cacheOrederTick.paresJson());

            log.info("订单[{}]创建完成，票数: {}", bizOrder.getId(), bizTicketOrderAddParam.getTicketCount());
        } catch (Exception e) {
            log.error("创建订单过程中发生异常: {}", e.getMessage(), e);
            throw new CommonException("创建订单失败: " + e.getMessage());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateReservationTime(BizOrderUpdateReservationTimeParam param) {
        // a. 获取订单实体
        BizOrder bizOrder = this.queryEntity(param.getId());

        // b. 检查订单是否存在原预约时间
        boolean hasExistingReservation = bizOrder.getReservationTime() != null;

        // c. 如果已存在预约时间，则不允许修改
        if (hasExistingReservation) {
            return false;
        }

        // d. 更新预约时间（只有当不存在预约时间时才会执行）
        bizOrder.setReservationTime(param.getReservationTime());
        this.updateById(bizOrder);

        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(BizTicketOrderEditParam bizTicketOrderEditParam) {
        BizOrder bizOrder = this.queryEntity(bizTicketOrderEditParam.getId());
        BeanUtil.copyProperties(bizTicketOrderEditParam, bizOrder);
        this.updateById(bizOrder);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<BizTicketOrderIdParam> bizTicketOrderIdParamList) {
        // 执行删除
        this.removeByIds(CollStreamUtil.toList(bizTicketOrderIdParamList, BizTicketOrderIdParam::getId));
    }

    @Override
    public BizOrder detail(BizTicketOrderIdParam bizTicketOrderIdParam) {
        return this.queryEntity(bizTicketOrderIdParam.getId());
    }

    @Override
    public BizOrder queryEntity(String id) {
        BizOrder bizOrder = this.getById(id);
        if(ObjectUtil.isEmpty(bizOrder)) {
            throw new CommonException("门票订单表不存在，id值为：{}", id);
        }
        return bizOrder;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void refund(BizTicketOrderIdParam bizTicketOrderIdParam) {
        BizOrder bizOrder = this.queryEntity(bizTicketOrderIdParam.getId());
//        if (!"已支付".equals(bizOrder.getStatus())) {
//            throw new CommonException("订单状态不正确");
//        }

        try {
            // 1. 删除用户票务记录
            List<BizUserTicket> list = bizUserTicketService.lambdaQuery()
                    .eq(BizUserTicket::getOrderId, bizOrder.getId())
                    .select(BizUserTicket::getId)
                    .list();
            bizUserTicketService.removeByIds(CollStreamUtil.toList(list, BizUserTicket::getId));

            // 2. 恢复门票库存
            if (bizOrder.getTicketCount() != null && bizOrder.getTicketCount() > 0) {
                ticketService.addInventory(bizOrder.getTicketId(), bizOrder.getTicketCount());

                // 3. 更新缓存中的库存
                String cacheKey = "spot:ticketid:" + bizOrder.getTicketId();
                String cacheValue = stringRedisTemplate.opsForValue().get(cacheKey);
                if (StrUtil.isNotBlank(cacheValue)) {
                    CacheOrederTick cacheOrderTick = CacheOrederTick.parseObj(cacheValue);
                    cacheOrderTick.setInventory(cacheOrderTick.getInventory() + bizOrder.getTicketCount());
                    stringRedisTemplate.opsForValue().set(cacheKey, cacheOrderTick.paresJson());
                }
            }

            // 4. 更新订单状态
            bizOrder.setStatus("已退款");
            this.updateById(bizOrder);

            log.info("订单{}退款成功，相关资源已释放", bizOrder.getId());
        } catch (Exception e) {
            log.error("订单退款处理异常，订单ID: {}", bizOrder.getId(), e);
            throw new CommonException("退款处理失败: " + e.getMessage());
        }
    }

    @Override
    public Page<BizOrder> spotpage(BizTicketOrderPageParam bizTicketOrderPageParam) {
        Page<BizOrder> bizOrderPage = new Page<>(bizTicketOrderPageParam.getCurrent(), bizTicketOrderPageParam.getSize());
        return bizTicketOrderMapper.spotImagepage(bizOrderPage, bizTicketOrderPageParam);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveFzOrder(BizFzOrder fzOrder) {
        if (fzOrder == null) {
            throw new CommonException("分账订单信息不能为空");
        }
        bizFzOrderMapper.insert(fzOrder);
        log.info("保存分账订单成功，订单ID：{}", fzOrder.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveFzOrderDetails(List<BizFzOrderDetail> fzDetails) {
        if (fzDetails == null || fzDetails.isEmpty()) {
            throw new CommonException("分账订单明细不能为空");
        }
        for (BizFzOrderDetail detail : fzDetails) {
            bizFzOrderDetailMapper.insert(detail);
        }
        log.info("保存分账订单明细成功，共{}条记录", fzDetails.size());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateFzOrder(BizFzOrder fzOrder) {
        if (fzOrder == null || StrUtil.isBlank(fzOrder.getId())) {
            throw new CommonException("分账订单信息不完整，无法更新");
        }
        int result = bizFzOrderMapper.updateById(fzOrder);
        if (result > 0) {
            log.info("更新分账订单成功，订单ID：{}", fzOrder.getId());
        } else {
            log.warn("更新分账订单失败，可能订单不存在，订单ID：{}", fzOrder.getId());
            throw new CommonException("更新分账订单失败，可能订单不存在");
        }
    }

    @Override
    public BizFzOrder getFzOrderByOrderId(String orderId) {
        if (StrUtil.isBlank(orderId)) {
            throw new CommonException("订单ID不能为空");
        }

        LambdaQueryWrapper<BizFzOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BizFzOrder::getOrderId, orderId);

        // 获取符合条件的第一条记录
        List<BizFzOrder> fzOrders = bizFzOrderMapper.selectList(queryWrapper);
        if (fzOrders != null && !fzOrders.isEmpty()) {
            log.info("根据订单ID: {} 获取到分账订单记录", orderId);
            return fzOrders.get(0);
        } else {
            log.warn("未找到订单ID: {} 的分账订单记录", orderId);
            return null;
        }
    }

    @Override
    public Page<BizTicketReservationResult> queryTravelAgencyTicketReservations(BizTicketReservationQueryParam param) {
        try {
            // 从登录用户信息中获取旅行社的组织ID
            SaBaseLoginUser loginUser = (SaBaseLoginUser) StpUtil.getTokenSession().get("loginUser");
            if (loginUser == null) {
                throw new CommonException("未获取到登录用户信息");
            }

            String orgId = loginUser.getOrgId();
            if (StrUtil.isBlank(orgId)) {
                throw new CommonException("未获取到用户组织信息");
            }

            // 构建查询条件
            Page<BizTicketReservationResult> page = new Page<>(
                    ObjectUtil.defaultIfNull(param.getCurrent(), 1),
                    ObjectUtil.defaultIfNull(param.getSize(), 10)
            );

            // 执行自定义SQL查询，联表查询订单、门票、用户票信息以及景点信息
            return bizTicketOrderMapper.queryTravelAgencyTicketReservations(page, orgId, param);

        } catch (Exception e) {
            log.error("查询旅行社门票预约情况失败", e);
            throw new CommonException("查询旅行社门票预约情况失败: " + e.getMessage());
        }
    }

}
